﻿/**
 * 矩阵端口控制模块(ES6)
 */
function PortControl() {
    this.maxPatchSwitchPortNum = 10;
    this.selectedDestPort = null;
    this.linkToSrcPort = null;
}

PortControl.prototype = {
    /**
     * 矩阵源端口选中处理
     * @param {any} portElement
     */
    selectSrcPort: function (portElement) {
        var selectedSrcPorts = this.getSelectedSrcPorts();
        if (selectedSrcPorts) {
            var preSelectedElement = selectedSrcPorts.not('#' + portElement.attr('id')).removeClass('matrixPort-selecting');
            if (preSelectedElement.hasClass('matrixPort-linkToSrc-selecting')) {
                preSelectedElement.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-linkToSrc');
            }

        }
        if (portElement.hasClass('matrixPort-linkToSrc')) {
            portElement.removeClass('matrixPort-linkToSrc').addClass('matrixPort-linkToSrc-selecting');
        } else if (portElement.hasClass('matrixPort-linkToSrc-selecting')) {
            portElement.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-linkToSrc');
        } else {
            portElement.toggleClass('matrixPort-selecting', !portElement.hasClass('matrixPort-selecting'));
        }
    },
    /**
     * 矩阵出端口选中处理
     * @param {any} portElement
     */
    selectDestPort: function (portElement) {
        portElement.toggleClass('matrixPort-selecting', !portElement.hasClass('matrixPort-selecting'));

        if ($('#canMutilSelect').is(':checked')) {
            var selectingPortCount = this.getSelectedDestPorts(true);
            if (selectingPortCount > this.maxPatchSwitchPortNum) {
                alert('已超过最大支持批量切换端口数[' + this.maxPatchSwitchPortNum + ']');
                portElement.removeClass('matrixPort-selecting');
            }

            this.selectedDestPort = null;
            this.cancelLinkToSrcPortSelectStatus();
            this.linkToSrcPort = null;

            var selectedDestPorts = this.getSelectedDestPorts();
            var firstSrcPort = this.getLinkToSrcPort($(selectedDestPorts.get(0)));
            var canSelectLinkToSrcPort = true;

            for (var i = 1; i < selectedDestPorts.length; i++) {
                var nextSrcPort = this.getLinkToSrcPort($(selectedDestPorts.get(i)));
                if (nextSrcPort != firstSrcPort) {
                    canSelectLinkToSrcPort = false;
                    break;
                }
            }

            //被动选中连接的源端口元素
            if (canSelectLinkToSrcPort) {
                this.selectLinkToSrcPort(firstSrcPort);
            }
            return;
        }

        //有被动选中状态的源端口
        if (this.linkToSrcPort) {
            this.cancelLinkToSrcPortSelectStatus(this.linkToSrcPort);
            this.linkToSrcPort = null;
        }

        //有选中状态的出端口
        if (this.selectedDestPort) {
            //取消上一次选中的端口
            this.selectedDestPort.removeClass('matrixPort-selecting');
            //当前选中端口和上一次选中端口相同
            if (this.selectedDestPort.attr('id') === portElement.attr('id')) {
                this.selectedDestPort = null;
                return;
            }
        }
        //记录选中的出端口元素
        this.selectedDestPort = portElement;

        //被动选中连接的源端口元素
        var srcPort = this.getLinkToSrcPort(portElement);
        this.selectLinkToSrcPort(srcPort);
    },
    /**
     * 获取和destPortElement指定的出端口连接中的源端口号
     * @param {any} destPortElement
     */
    getLinkToSrcPort: function (destPortElement) {
        return destPortElement.attr('data-srcPort');
    },
    /**
     * 更新和destPortElement指定的出端口连接中的源端口号
     * @param {any} destPortElement
     */
    setLinkToSrcPort: function (destPortElement, port) {
        destPortElement.attr('data-srcPort', port);
    },
    /**
     * 被动选中源端口
     * @param {any} port
     */
    selectLinkToSrcPort: function (port) {
        if (!port) {
            return;
        }

        this.linkToSrcPort = $('#srcPorts').children('#port' + port);
        if (this.linkToSrcPort) {
            if (this.linkToSrcPort.hasClass('matrixPort-selecting')) {
                this.linkToSrcPort.addClass('matrixPort-linkToSrc-selecting');
            } else {
                this.linkToSrcPort.addClass('matrixPort-linkToSrc');
            }

            var parentHeight = $('#srcPorts').innerHeight();
            var linkToSrcPortTop = this.linkToSrcPort.position().top - 2;
            var currentScrollTop = $('#srcPorts').scrollTop();

            var offsetTop = 0;
            if (linkToSrcPortTop > parentHeight) {
                //向下滚动偏移量
                offsetTop = linkToSrcPortTop - parentHeight + currentScrollTop
            } else if (linkToSrcPortTop <= 0) {
                //向上滚动偏移量
                offsetTop = linkToSrcPortTop + currentScrollTop - this.linkToSrcPort.outerHeight(true)
            }
            if (offsetTop > 0) {
                $('#srcPorts').animate({
                    scrollTop: offsetTop
                }, 200);
            }
        }
    },
    /**
     * 取消所有端口选中状态
     */
    cancelPortSelectStatus: function () {
        var selectingPorts = this.getSelectedDestPorts();
        if (selectingPorts) {
            selectingPorts.removeClass('matrixPort-selecting');
        }

        //取消被动选中的源端口
        this.cancelLinkToSrcPortSelectStatus();
    },
    /**
     * 取消被动选中的源端口
     */
    cancelLinkToSrcPortSelectStatus: function (portElement) {
        if (portElement) {
            portElement.removeClass('matrixPort-linkToSrc');
            if (portElement.hasClass('matrixPort-linkToSrc-selecting')) {
                portElement.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-selecting');
            }
            return;
        }

        var srcPorts = $('#srcPorts').children('.matrixPort-linkToSrc');
        if (srcPorts.length > 0) {
            srcPorts.removeClass('matrixPort-linkToSrc');
            return;
        }

        srcPorts = $('#srcPorts').children('.matrixPort-linkToSrc-selecting');
        if (srcPorts.length > 0) {
            srcPorts.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-selecting');
            return;
        }
    },
    /**
     * 判断端口是否处于选中状态
     * @param {any} portElement
     */
    portIsSelecting: function (portElement) {
        return portElement && portElement.hasClass('matrixPort-selecting');
    },
    /**
     * 获取选中状态的出端口，returnCount为true时，返回选中端口的数量
     * @param {any} returnCount
     */
    getSelectedDestPorts: function (returnCount) {
        return this.getSelectedPorts('#destPorts', returnCount);
    },
    /**
     * 获取选中状态的源端口，returnCount为true时，返回选中端口的数量
     * @param {any} returnCount
     */
    getSelectedSrcPorts: function (returnCount) {
        return this.getSelectedPorts('#srcPorts', returnCount);
    },
    /**
     * 获取containerId指定元素内的选中端口元素，returnCount为true时，返回选中端口的数量
     * @param {any} containerId
     * @param {any} returnCount
     */
    getSelectedPorts: function (containerId, returnCount) {
        var selectingPorts = $(containerId).children('.matrixPort-selecting');
        if (selectingPorts.length == 0) {
            selectingPorts = $(containerId).children('.matrixPort-linkToSrc-selecting');
        }
        return returnCount ? selectingPorts.length : selectingPorts;
    },
    /**
    * 取消被动选中的源端口
    */
    cancelLinkToSrcPortSelectStatus: function (portElement) {
        if (portElement) {
            portElement.removeClass('matrixPort-linkToSrc');
            if (portElement.hasClass('matrixPort-linkToSrc-selecting')) {
                portElement.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-selecting');
            }
            return;
        }

        var srcPorts = $('#srcPorts').children('.matrixPort-linkToSrc');
        if (srcPorts.length > 0) {
            srcPorts.removeClass('matrixPort-linkToSrc');
            return;
        }

        srcPorts = $('#srcPorts').children('.matrixPort-linkToSrc-selecting');
        if (srcPorts.length > 0) {
            srcPorts.removeClass('matrixPort-linkToSrc-selecting').addClass('matrixPort-selecting');
            return;
        }
    },
    /**
    * 判断port1和port2是否相同
    * @param {any} port1
    * @param {any} port2
    */
    portEquals: function (port1, port2) {
        return (port1 && port1.attr('id')) === (port2 && port2.attr('id'));
    },
    /**
     * 设置端口操作失败样式
     * @param {any} portElement
     */
    setPortErrorStyle: function (portElement) {
        if (!portElement.hasClass('matrixPort-locking-error')) {
            portElement.addClass('matrixPort-locking-error');
        }
    },
    /**
     * 取消端口操作失败样式
     * @param {any} portElement
     */
    removePortErrorStyle: function (portElement) {
        if (portElement.hasClass('matrixPort-locking-error')) {
            portElement.removeClass('matrixPort-locking-error');
        }
    }
}
